/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package AccesoDatos.DAOSocket;

import AccesoDatos.IDAO.IDAOArchivo;
import ObjetoDominio.Archivo;
import ObjetoDominio.ArchivoXML;
import ObjetoDominio.Servidor;
import ObjetoDominio.Usuario;
import Proxy.ProxyArchivo;
import Proxy.ProxyUsuario;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.OutputStream;
import java.util.List;

/**
 *Clase que implementa la interfaz IDAOArchivo
 * para el caso particular Local
 * @author opr
 */
public class DAOArchivoSocket implements IDAOArchivo {

    private Servidor _servidor;
    public DAOArchivoSocket(Servidor servidor) {
        _servidor = servidor;
    }

    /**
     * metodo que descarga los archivos desde la fuente por socket
     * @param arhivo datos del archivo a descargar
     */
    @Override
    public void DescargarArchivo(Archivo arhivo, Usuario usuario) {
        try
        {
            _servidor.AbrirConexion();            
            OutputStream flujoSalida = _servidor.getViaComunicacion().getOutputStream();
            DataOutputStream salida = new DataOutputStream( flujoSalida );
            salida.writeUTF(ArchivoXML.CrearMensaje("descargar"));
            salida.writeUTF(ProxyUsuario.TransformarUsuarioXml(usuario));
            salida.writeUTF(ArchivoXML.CrearMensaje(arhivo.getNombre()));
            salida.writeUTF(ArchivoXML.CrearMensaje(String.valueOf(arhivo.getDescargado())));
            FileOutputStream fos;
            System.out.println(arhivo.getDescargado());
            if(arhivo.getDescargado() == 0)
                fos = new FileOutputStream(usuario.getNombre() + "/" + arhivo.getNombre());
            else
                fos = fos = new FileOutputStream(usuario.getNombre() + "/" + arhivo.getNombre(),true);
            ObjectInputStream ois = new ObjectInputStream(_servidor.getViaComunicacion()
                    .getInputStream());
            Object mensajeAux;
            Archivo mensajeRecibido;
            do
            {
                mensajeAux = ois.readObject();
                if (mensajeAux instanceof Archivo)
                {
                    mensajeRecibido = (Archivo) mensajeAux;
                     fos.write(mensajeRecibido.getContenidoFichero(),
                             0, mensajeRecibido.getBytesValidos());
                    arhivo.setDescargado(arhivo.getDescargado() +
                            mensajeRecibido.getBytesValidos());
                } 
                else{
                    System.err.println("Mensaje no esperado "
                            + mensajeAux.getClass().getName());
                    break;
                }
            } while (!mensajeRecibido.isUltimoMensaje());
            fos.flush();
            fos.close();
            ois.close();
            _servidor.CerrarConexion();

        } catch (Exception e)
        {
            System.out.println(e);
        }
    }

    @Override
    public void ReanudarDescarga(Archivo arhivo) {
        throw new UnsupportedOperationException("Not supported yet.");
    }

    @Override
    public void CargarArchivo(Archivo arhivo, Usuario usuario) {
        try
        {
             _servidor.AbrirConexion();            
            OutputStream flujoSalida = _servidor.getViaComunicacion().getOutputStream();
            InputStream flujoEntrada = _servidor.getViaComunicacion().getInputStream();
            DataOutputStream salida = new DataOutputStream( flujoSalida );
            salida.writeUTF(ArchivoXML.CrearMensaje("cargarServidor"));
            salida.writeUTF(ProxyUsuario.TransformarUsuarioXml(usuario));
            salida.writeUTF(ArchivoXML.CrearMensaje(arhivo.getNombre()));
            salida.writeUTF(ArchivoXML.CrearMensaje(String.valueOf(arhivo.getTamaño())));
            DataInputStream entrada = new DataInputStream(flujoEntrada);
            arhivo.setDescargado(Long.parseLong(ArchivoXML.ObtenerMensaje(entrada.readUTF())));
            System.out.println("info de el " + arhivo.getDescargado() + " " + arhivo.getTamaño());
            if(arhivo.getDescargado()!= -1){
                boolean enviadoUltimo=false;
                ObjectOutputStream oos = new ObjectOutputStream(flujoSalida);
                FileInputStream fis = new FileInputStream(arhivo.getRuta());
                Archivo mensaje = new Archivo();
                mensaje.setNombre(arhivo.getNombre());
                int leidos = fis.read(mensaje.getContenidoFichero());
                int tamaño = leidos;
                if(arhivo.getDescargado() != 0)
                    arhivo.setDescargado(arhivo.getDescargado() + 
                            Archivo.LONGITUD_MAXIMA);
                while (leidos > -1)
                {
                    mensaje.setBytesValidos(leidos);
                    if (leidos < Archivo.LONGITUD_MAXIMA)
                    {
                        mensaje.setUltimoMensaje(true);
                        enviadoUltimo=true;
                    }
                    else
                        mensaje.setUltimoMensaje(false);
                    if(tamaño >= arhivo.getDescargado()){
                       // Thread.sleep(20);
                        oos.writeObject(mensaje);
                        arhivo.setDescargado(arhivo.getDescargado() +
                                mensaje.getBytesValidos());
                        entrada.readUTF();
                    }

                    if (mensaje.isUltimoMensaje())
                        break;
                    mensaje = new Archivo();
                    mensaje.setNombre(arhivo.getNombre());
                    leidos = fis.read(mensaje.getContenidoFichero());
                    tamaño = tamaño + leidos;
                }

                if (enviadoUltimo==false)
                {
                    mensaje.setUltimoMensaje(true);
                    mensaje.setBytesValidos(0);
                    oos.writeObject(mensaje);
                    entrada.readUTF();
                }
                oos.flush();
                oos.close();
            }
            System.out.println("Termine");
            _servidor.CerrarConexion();
        }catch (Exception e)
        {
        }
    }

    @Override
    public void ReanudarCargar(Archivo arhivo) {
        throw new UnsupportedOperationException("Not supported yet.");
    }

    @Override
    public List<Archivo> ObtenerListaArchivos(Usuario usuario) {
        throw new UnsupportedOperationException("Not supported yet.");
    }

    @Override
    public void EnviarListaArchivos(List<Archivo> archivos) {
        try {
            OutputStream flujoSalida = _servidor.getViaComunicacion().getOutputStream();
            DataOutputStream salida = new DataOutputStream( flujoSalida );
            salida.writeUTF(ProxyArchivo.TransformarListaArchivoXml(archivos));
            _servidor.CerrarConexion();
        } catch (Exception e) {
            System.out.println(e);
        }
    }
    
}
